import { Fragment as _Fragment, withDirectives as _withDirectives, vShow as _vShow, createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
import { ref, watch, provide, Teleport, nextTick, computed, onMounted, Transition, onActivated, onDeactivated, defineComponent } from "vue";
import { popupSharedProps } from "./shared.mjs";
import { isDef, extend, makeStringProp, callInterceptor, createNamespace, HAPTICS_FEEDBACK } from "../utils/index.mjs";
import { useEventListener } from "@vant/use";
import { useExpose } from "../composables/use-expose.mjs";
import { useLockScroll } from "../composables/use-lock-scroll.mjs";
import { useLazyRender } from "../composables/use-lazy-render.mjs";
import { POPUP_TOGGLE_KEY } from "../composables/on-popup-reopen.mjs";
import { useGlobalZIndex } from "../composables/use-global-z-index.mjs";
import { useScopeId } from "../composables/use-scope-id.mjs";
import { Icon } from "../icon/index.mjs";
import { Overlay } from "../overlay/index.mjs";
const popupProps = extend({}, popupSharedProps, {
  round: Boolean,
  position: makeStringProp("center"), // 弹出位置, 可选值为top bottom right left
  closeIcon: makeStringProp("cross"),
  closeable: Boolean,
  transition: String, // 动画类名, 等价于 transtion的name属性
  iconPrefix: String,
  closeOnPopstate: Boolean,
  closeIconPosition: makeStringProp("top-right"),
  safeAreaInsetTop: Boolean,
  safeAreaInsetBottom: Boolean
});
const [name, bem] = createNamespace("popup");
var stdin_default = defineComponent({
  name,
  inheritAttrs: false,
  props: popupProps,
  // 使用props.show和emit 'update:show'实现双向绑定
  emits: ["open", "close", "opened", "closed", "keydown", "update:show", "clickOverlay", "clickCloseIcon"],
  setup(props, {
    emit,
    attrs,
    slots
  }) {
    let opened; // 是否打开
    let shouldReopen; // 是否需要重新打开
    const zIndex = ref();
    const popupRef = ref();
    // lazyRender为false, 未打开也渲染弹框内容
    const lazyRender = useLazyRender(() => props.show || !props.lazyRender);
    // 计算dialog的样式
    const style = computed(() => {
      const style2 = {
        zIndex: zIndex.value
      };
      if (isDef(props.duration)) {
        // 居中时使用动画 其他位置使用过滤
        const key = props.position === "center" ? "animationDuration" : "transitionDuration";
        style2[key] = `${props.duration}s`;
      }
      return style2;
    });

    // 打开popup的同时,根据useGlobalZIndex全局更新当前组件的index
    // 触发: watch中show / onMounted试show初始为true
    const open = () => {
      if (!opened) {
        opened = true;
        zIndex.value = props.zIndex !== void 0 ? +props.zIndex : useGlobalZIndex();
        emit("open");
      }
    };
    // 关闭popup方法,可以被callInterceptor拦截
    // 触发: 点击遮罩 / onDeactiveed  / onClickCloseIcon / wahtch.show  / popstate事件触发
    const close = () => {
      if (opened) {
        callInterceptor(props.beforeClose, {
          done() {
            opened = false;
            emit("close");
            // 更新双休绑定值
            emit("update:show", false);
          }
        });
      }
    };

    // 点击遮罩关闭popup
    const onClickOverlay = (event) => {
      emit("clickOverlay", event);
      if (props.closeOnClickOverlay) {
        close();
      }
    };

    // popup上一个兄弟节点为overlay
    // 遮罩层渲染函数
    const renderOverlay = () => {
      if (props.overlay) {
        return _createVNode(Overlay, _mergeProps({
          "show": props.show,
          "class": props.overlayClass,
          "zIndex": zIndex.value,
          "duration": props.duration,
          "customStyle": props.overlayStyle,
          "role": props.closeOnClickOverlay ? "button" : void 0,
          "tabindex": props.closeOnClickOverlay ? 0 : void 0
        }, useScopeId(), {
          "onClick": onClickOverlay
        }), {
          // 传递插槽 穿透传递
          default: slots["overlay-content"]
        });
      }
    };
    const onClickCloseIcon = (event) => {
      emit("clickCloseIcon", event);
      close();
    };

    // 关闭按钮渲染函数
    const renderCloseIcon = () => {
      if (props.closeable) {
        return _createVNode(Icon, {
          "role": "button",
          "tabindex": 0,
          "name": props.closeIcon,
          "class": [bem("close-icon", props.closeIconPosition), HAPTICS_FEEDBACK],
          "classPrefix": props.iconPrefix,
          "onClick": onClickCloseIcon
        }, null);
      }
    };

    // 设定过渡开始结束事件 放在异步宏任务中执行
    let timer;
    const onOpened = () => {
      if (timer)
        clearTimeout(timer);
      timer = setTimeout(() => {
        emit("opened");
      });
    };

    const onClosed = () => emit("closed");
    const onKeydown = (event) => emit("keydown", event);

    // lazyRender接收真的渲染函数,会根据useLazyRender传入的get来选择初始化
    // 返回值为插槽函数
    const renderPopup = lazyRender(() => {
      var _a;
      const {
        round,
        position,
        safeAreaInsetTop,
        safeAreaInsetBottom
      } = props;
      return _withDirectives(_createVNode("div", _mergeProps({
        "ref": popupRef,
        "style": style.value,
        "role": "dialog",
        "tabindex": 0,
        "class": [bem({
          round,
          [position]: position
        }), {
          "van-safe-area-top": safeAreaInsetTop,
          "van-safe-area-bottom": safeAreaInsetBottom
        }],
        "onKeydown": onKeydown
      }, attrs, useScopeId()), [(_a = slots.default) == null ? void 0 : _a.call(slots), renderCloseIcon()]), [[_vShow, props.show]]);
    });

    // 动画包裹的content渲染函数
    const renderTransition = () => {
      const {
        position,
        transition,
        transitionAppear
      } = props;
      const name2 = position === "center" ? "van-fade" : `van-popup-slide-${position}`;
      return _createVNode(Transition, {
        "name": transition || name2,
        "appear": transitionAppear,
        "onAfterEnter": onOpened,
        "onAfterLeave": onClosed
      }, {
        // 使用default 插槽函数
        default: renderPopup
      });
    };

    watch(() => props.show, (show) => {
      if (show && !opened) {
        open();
        if (attrs.tabindex === 0) {
          nextTick(() => {
            var _a;
            (_a = popupRef.value) == null ? void 0 : _a.focus();
          });
        }
      }
      if (!show && opened) {
        opened = false;
        emit("close");
      }
    });

    // 暴露dialog实例
    useExpose({
      popupRef
    });

    // 弹窗是否锁住 不让主页面滚动,在dialog中滑动不会触发父级滚动
    useLockScroll(popupRef, () => props.show && props.lockScroll);
    // 监听历史记录回退 自动关闭弹框
    useEventListener("popstate", () => {
      if (props.closeOnPopstate) {
        close();
        shouldReopen = false;
      }
    });

    onMounted(() => {
      if (props.show) {
        open();
      }
    });
    onActivated(() => {
      if (shouldReopen) {
        emit("update:show", true);
        shouldReopen = false;
      }
    });
    // onDeactivated且teleport时,再onActivated需要直接自动打开
    onDeactivated(() => {
      if (props.show && props.teleport) {
        close();
        shouldReopen = true;
      }
    });
    
    // 注入 开启关闭状态给子组件使用
    // 包裹子组件 swipe  tabs NoticeBar时, 状态改变会触发相关组件相关功能
    provide(POPUP_TOGGLE_KEY, () => props.show);
    return () => {
      // teleport在vue3中允许将本组件节点挂在to设定的其他位置
      if (props.teleport) {
        return _createVNode(Teleport, {
          "to": props.teleport
        }, {
          default: () => [renderOverlay(), renderTransition()]
        });
      }
      // _Fragment允许模板下可以有多个节点
      return _createVNode(_Fragment, null, [renderOverlay(), renderTransition()]);
    };
  }
});
export {
  stdin_default as default,
  popupProps
};
